package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"

	"go-file-perception-model/internal/config"
	"go-file-perception-model/internal/handler"
	"go-file-perception-model/internal/logger"
	"go-file-perception-model/internal/repository"
	"go-file-perception-model/internal/service"
	"go-file-perception-model/pkg/embedding"
	"go-file-perception-model/pkg/vector"

	"github.com/gin-gonic/gin"
)

func main() {
	// 初始化日志系统
	logger.InitLogger()
	log.Println("Starting Go File Perception Model Server...")

	// 确保数据目录存在
	if err := os.MkdirAll("./data", 0755); err != nil {
		log.Fatalf("Failed to create data directory: %v", err)
	}

	// 加载配置
	cfg, err := config.LoadConfig()
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}

	// 初始化嵌入模型
	bgeConfig := &embedding.BGEServiceConfig{
		Host:    cfg.BGEService.Host,
		Port:    cfg.BGEService.Port,
		APIKey:  cfg.BGEService.APIKey,
		Timeout: cfg.BGEService.Timeout,
	}
	embeddingModel, err := embedding.NewBGEModel(bgeConfig)
	if err != nil {
		log.Printf("Warning: Failed to initialize embedding model: %v", err)
		log.Println("Continuing without embedding model functionality...")
		embeddingModel = nil
	}

	// 初始化向量数据库
	// 使用真实的Qdrant向量数据库服务
	// 尝试使用HTTP API端口6333，如果失败则尝试gRPC端口
	var vectorDB *vector.QdrantDB
	vectorDB, err = vector.NewQdrantDBWithAPIKey(cfg.VectorDB.Host, cfg.VectorDB.Port, cfg.VectorDB.APIKey)
	if err != nil {
		log.Printf("Failed to connect to Qdrant on port %d, trying gRPC port %d...", cfg.VectorDB.Port, cfg.VectorDB.GRPCPort)
		vectorDB, err = vector.NewQdrantDBWithAPIKey(cfg.VectorDB.Host, cfg.VectorDB.GRPCPort, cfg.VectorDB.APIKey)
		if err != nil {
			log.Printf("Warning: Failed to initialize vector database: %v", err)
			log.Println("Continuing without vector database functionality...")
			vectorDB = nil
		}
	}

	// 不在启动时创建默认集合，而是根据用户设置的索引目录来创建集合

	// 初始化存储库
	var fileRepo repository.FileRepository
	// 检查vectorDB是否为nil，如果是则创建一个不使用向量数据库的存储库
	if vectorDB == nil {
		log.Println("Warning: Vector database is not available, creating repository without vector DB")
		fileRepo = repository.NewFileRepository(nil)
	} else {
		fileRepo = repository.NewFileRepository(vectorDB)
	}

	// 初始化服务
	var fileService *service.FileService
	// 检查embeddingModel是否为nil，如果是则创建一个不使用嵌入模型的服务
	if embeddingModel == nil {
		log.Println("Warning: Embedding model is not available, creating service without embedding model")
		fileService = service.NewFileService(fileRepo, nil, &cfg.FileIndex, cfg)
	} else {
		fileService = service.NewFileService(fileRepo, embeddingModel, &cfg.FileIndex, cfg)
	}

	// 初始化配置中的索引目录
	if len(cfg.FileIndex.IndexDirectories) > 0 {
		log.Printf("Initializing %d configured directories...", len(cfg.FileIndex.IndexDirectories))
		for _, dir := range cfg.FileIndex.IndexDirectories {
			if err := initializeDirectory(fileService, dir); err != nil {
				log.Printf("Warning: Failed to initialize directory %s: %v", dir, err)
			} else {
				log.Printf("Directory initialized: %s", dir)
			}
		}
	}

	// 初始化目录树服务
	fileCollector := service.NewFileCollector(&cfg.FileIndex)
	directoryTreeService := service.NewDirectoryTreeService(fileCollector, fileService.GetIndexManager(), cfg)

	// 初始化基于数据库的目录树服务
	fileMonitorRepo, err := repository.NewFileMonitorRepository("./data/file_monitor.db")
	if err != nil {
		log.Printf("Warning: Failed to initialize file monitor repository: %v", err)
		fileMonitorRepo = nil
	}
	var dbDirectoryTreeService *service.DBDirectoryTreeService
	if fileMonitorRepo != nil {
		dbDirectoryTreeService = service.NewDBDirectoryTreeService(fileMonitorRepo, cfg)
	}

	// 初始化处理器
	fileHandler := handler.NewFileHandler(fileService)
	searchHandler := handler.NewSearchHandler(fileService)
	systemHandler := handler.NewSystemHandler(fileService)
	directoryTreeHandler := handler.NewDirectoryTreeHandler(directoryTreeService)

	// 初始化基于数据库的目录树处理器
	var dbDirectoryTreeHandler *handler.DBDirectoryTreeHandler
	if dbDirectoryTreeService != nil {
		dbDirectoryTreeHandler = handler.NewDBDirectoryTreeHandler(dbDirectoryTreeService)
	}

	// 设置Gin模式
	if cfg.Server.Mode == "release" {
		gin.SetMode(gin.ReleaseMode)
	}

	// 创建Gin引擎
	r := gin.Default()

	// 注册路由
	api := r.Group("/api/v1")
	{
		// 文件索引相关API
		api.POST("/index", fileHandler.IndexFiles)
		api.GET("/index/status", fileHandler.GetIndexStatus)

		// 多目录索引管理API
		api.GET("/directories", fileHandler.GetIndexDirectories)
		api.POST("/directories", fileHandler.AddIndexDirectory)
		api.POST("/directories/set", fileHandler.SetIndexDirectories)
		api.DELETE("/directories", fileHandler.RemoveIndexDirectory)
		api.PUT("/directories/status", fileHandler.UpdateIndexDirectoryStatus)
		api.DELETE("/index/chunks", fileHandler.ClearIndexChunks)
		api.POST("/index/clear/directories", fileHandler.ClearIndexChunks)
		api.DELETE("/index/clear", fileHandler.ClearAllIndexChunks)

		// 系统状态API
		api.GET("/system/status", systemHandler.GetSystemStatus)
		api.GET("/system/stats", systemHandler.GetSystemStats)

		// 文件检索相关API
		api.POST("/search/semantic", searchHandler.SemanticSearch)
		api.POST("/search/regex", searchHandler.RegexSearch)

		// 文件列表API
		api.GET("/files", systemHandler.GetFileList)

		// 验证数据存储API
		api.GET("/points/:id", systemHandler.GetPointByID)

		// 文件内容API
		api.GET("/files/content", systemHandler.GetFileContent)

		// 目录树相关API
		api.GET("/directory-tree", directoryTreeHandler.GetDirectoryTree)
		api.POST("/directory-tree", directoryTreeHandler.GetDirectoryTreeByPost)
		api.POST("/directory-tree/search", directoryTreeHandler.SearchDirectoryTree)

		// 基于数据库的目录树搜索API
		if dbDirectoryTreeHandler != nil {
			api.GET("/directory-tree/db-search", dbDirectoryTreeHandler.SearchFilesInDatabaseByGet)
			api.POST("/directory-tree/db-search", dbDirectoryTreeHandler.SearchFilesInDatabase)
		}

		// 配置相关API
		api.GET("/config", fileHandler.GetConfig)
		api.POST("/config", fileHandler.SaveConfig)
	}

	// 静态文件服务
	r.Static("/static", "./web/static")
	r.LoadHTMLGlob("web/templates/*")
	r.GET("/", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", gin.H{
			"title": "Go文件感知国产模型",
		})
	})

	// 启动服务器
	server := &http.Server{
		Addr:    fmt.Sprintf(":%d", cfg.Server.Port),
		Handler: r,
	}

	// 启动HTTP服务器
	go func() {
		log.Printf("Server starting on port %d...", cfg.Server.Port)
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("Failed to start server: %v", err)
		}
	}()

	// 启动文件监控服务
	go func() {
		if err := fileService.StartFileMonitoring(); err != nil {
			log.Printf("Failed to start file monitoring: %v", err)
		}
	}()

	// 优雅关闭
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Println("Shutting down server...")

	if err := server.Close(); err != nil {
		log.Printf("Server forced to shutdown: %v", err)
	}

	log.Println("Server exited")
}

// initializeDirectory 初始化目录
func initializeDirectory(fileService *service.FileService, directory string) error {
	// 检查目录是否存在
	if _, err := os.Stat(directory); os.IsNotExist(err) {
		return fmt.Errorf("directory does not exist: %s", directory)
	}

	// 添加目录到索引目录列表（如果还没有的话）
	if err := fileService.AddIndexDirectory(directory); err != nil {
		return fmt.Errorf("failed to add index directory: %w", err)
	}

	return nil
}
